home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Add-Ons / After Dark / Twist 1.0b1 / FindBrowser.c < prev    next >
Text File  |  1996-07-02  |  7KB  |  314 lines

  1. /* FindBrowser.c
  2.  * Look for and launch a Web browser that supports the GetURL event
  3.  * Copyright ©1996 Michael D. Crawford.  All Rights Reserved.
  4.  * You may use this code on the condition that you read the following web page:
  5.  * http://www.scruznet.com/~crawford/WordServices/wdsvindex.html
  6.  *  1 Jul 96 Mike Crawford crawford@scruznet.com
  7.  */
  8.  
  9. #include "FindBrowser.h"
  10. #include "FindProcess.h"
  11.  
  12. OSErr LookForProcess( OSType creator, Boolean *gotItPtr );
  13. OSErr LaunchTheApp( FSSpecPtr specPtr );
  14. OSErr SearchVolForBrowser( short vRef,
  15.                             Boolean *gotItPtr,
  16.                             OSType **creators,
  17.                             short numCreators,
  18.                             FSSpecPtr specPtr,
  19.                             OSType *creatorPtr );
  20.  
  21. OSErr FindBrowser( OSType *creatorPtr )
  22. {
  23.     OSType    **creators;
  24.     OSErr    err;
  25.     short    i;
  26.     short    numCreators;
  27.     Boolean    gotIt;
  28.     ProcessSerialNumber psn;
  29.     ProcessInfoRec pInfo;
  30.     FSSpec fSpec;
  31.     Str255    procName;
  32.     VolumeParam    vPB;
  33.     
  34.     *creatorPtr = 'null';
  35.     
  36.     creators = (OSType**)GetResource( 'Cr8r', 128 );
  37.     if ( !creators )
  38.         return resNotFound;
  39.     
  40.     numCreators = GetHandleSize( (Handle)creators ) / sizeof( OSType );
  41.     
  42.     // Search the running processes for one we know about
  43.     
  44.     for ( i = 0; i < numCreators; i++ ){
  45.         gotIt = FindAProcess( (*creators)[ i ],
  46.                                 &psn,
  47.                                 &pInfo,
  48.                                 &fSpec,
  49.                                 procName );
  50.         if ( gotIt ){
  51.             *creatorPtr = (*creators)[ i ];
  52.             return noErr;
  53.         }
  54.     }
  55.     
  56.     vPB.ioCompletion = (IOCompletionUPP)NULL;
  57.     vPB.ioVolIndex = 1;
  58.     vPB.ioNamePtr = (StringPtr)NULL;
  59.     
  60.     do {
  61.         err = PBGetVInfoSync( (ParamBlockRec*)&vPB );
  62.         if ( err == nsvErr )
  63.             return noErr;            // Out of volumes to search, haven't found any browsers
  64.         if ( err )
  65.             return err;
  66.         
  67.         err = SearchVolForBrowser( vPB.ioVRefNum,
  68.                                     &gotIt,
  69.                                     creators, 
  70.                                     numCreators, 
  71.                                     &fSpec, 
  72.                                     creatorPtr );
  73.         if ( gotIt ){
  74.             err = LaunchTheApp( &fSpec );
  75.             return err;
  76.                 
  77.         }
  78.         
  79.         vPB.ioVolIndex++;
  80.     }while( !err && !gotIt );
  81.         
  82.     return noErr;
  83. }
  84.  
  85. OSErr SearchVolForBrowser( short vRef,
  86.                             Boolean *gotItPtr,
  87.                             OSType **creators,
  88.                             short numCreators,
  89.                             FSSpecPtr specPtr,
  90.                             OSType *creatorPtr )
  91. {
  92.     short    i;
  93.     DTPBRec    dPB;
  94.     short    refNum;
  95.     Str255    name;
  96.     FInfo    fndrInfo;
  97.     OSErr    err;
  98.     
  99.     *gotItPtr = false;
  100.  
  101.     dPB.ioNamePtr = (StringPtr)NULL;
  102.     dPB.ioVRefNum = vRef;
  103.     
  104.     err = PBDTGetPath( &dPB );
  105.     if ( err )
  106.         return err;
  107.     
  108.     refNum = dPB.ioDTRefNum;
  109.     
  110.     dPB.ioCompletion = (IOCompletionUPP)NULL;
  111.     dPB.ioNamePtr = name;
  112.     
  113.     for ( i = 0; i < numCreators; i++ ){
  114.         dPB.ioFileCreator = (*creators)[ i ];
  115.         
  116.         dPB.ioIndex = 1;
  117.         
  118.         do{
  119.             err = PBDTGetAPPL( &dPB, false );
  120.             if ( err == afpItemNotFound )
  121.                 break;
  122.             if ( err )
  123.                 return err;
  124.             
  125.             // We got the application info, but it is possible that the application
  126.             // has been deleted without the desktop file being updated.  Check to
  127.             // see that the file is still there.
  128.             
  129.             err = HGetFInfo( vRef, dPB.ioAPPLParID, name, &fndrInfo );
  130.             if ( !err ){
  131.                 err = FSMakeFSSpec( vRef, dPB.ioAPPLParID, name, specPtr );
  132.                 if ( err )
  133.                     return err;
  134.                 
  135.                 *creatorPtr = dPB.ioFileCreator;
  136.  
  137.                 *gotItPtr = true;
  138.                 return noErr;
  139.             }
  140.         }while( !err );    
  141.     }
  142.     
  143.     return noErr;
  144. }
  145.  
  146. OSErr LaunchTheApp( FSSpecPtr specPtr )
  147. {
  148.     OSErr        err;
  149.     Boolean        changed;
  150.     AppleEvent        launchEvent;
  151.     AppleEvent        replyEvent;
  152.     AEDesc            aliasDesc;
  153.     AEDesc            folderDesc;
  154.     FSSpec            folderSpec;
  155.     AEDesc            finderAddr;
  156.     DescType        finderSig;
  157.     AliasHandle        fAliasHdl;
  158.     AliasHandle        appAliasHdl;
  159.     AEDescList        aliasList;
  160.  
  161.     // Launch the browser by sending an Open Selection apple event to the Finder.
  162.     // We need to do this so that the process shows up in the application menu, so that
  163.     // we see zoomrects on launch, and so that the application's icon is dimmed in its
  164.     // Finder window
  165.  
  166.     // Taken from Writeswell Jr.'s LaunchSpeller in DoChecking.c
  167.  
  168.     
  169.     /* make an alias for the parent folder */
  170.     
  171.     err = FSMakeFSSpec( specPtr->vRefNum,
  172.                         specPtr->parID,
  173.                         (StringPtr)NULL,
  174.                         &folderSpec );
  175.     if ( err ){
  176.         return err;
  177.     }
  178.     
  179.     err = NewAlias( (FSSpecPtr)NULL, &folderSpec, &fAliasHdl );
  180.     if ( err ){
  181.         return err;
  182.     }
  183.  
  184.     /* Create the event to send to the Finder */
  185.     
  186.     finderSig = 'MACS';                        /* Creator code of finder; type is 'FNDR' */
  187.     err = AECreateDesc( typeApplSignature,
  188.                         (Ptr)&finderSig,
  189.                         sizeof( finderSig ),
  190.                         &finderAddr );
  191.     if ( err ){
  192.         return err;
  193.     }    
  194.                 
  195.     err = AECreateAppleEvent( kAEFinderEvents,
  196.                                 kAEOpenSelection,
  197.                                 &finderAddr,
  198.                                 kAutoGenerateReturnID,
  199.                                 kAnyTransactionID,
  200.                                 &launchEvent );
  201.     
  202.     if ( err ){
  203.         return err;
  204.     }
  205.     err = AEDisposeDesc( &finderAddr );
  206.     if ( err ){
  207.         return err;
  208.     }
  209.     
  210.     /* Insert the folder alias record as the direct object of the batch event */
  211.  
  212.     /* First make a descriptor of the alias */
  213.     HLock( (Handle) fAliasHdl );
  214.  
  215.     err = AECreateDesc( typeAlias,
  216.                         (Ptr)*fAliasHdl,
  217.                         (*fAliasHdl)->aliasSize,
  218.                         &folderDesc );
  219.  
  220.     HUnlock( (Handle) fAliasHdl );
  221.     DisposHandle( (Handle) fAliasHdl );
  222.  
  223.     if ( err ){
  224.         return err;
  225.     }    
  226.     
  227.     err = AEPutParamDesc( &launchEvent,
  228.                             keyDirectObject,
  229.                             &folderDesc );
  230.     if ( err ){
  231.         return err;
  232.     }
  233.     err = AEDisposeDesc( &folderDesc );
  234.     if ( err ){
  235.         return err;
  236.     }
  237.  
  238.     /* Put the application alias on the event */
  239.     err = NewAlias( (FSSpecPtr)NULL, specPtr, &appAliasHdl );
  240.     if ( err ){
  241.         return err;
  242.     }
  243.  
  244.     HLock( (Handle) appAliasHdl );
  245.  
  246.     err = AECreateDesc( typeAlias,
  247.                         (Ptr)*appAliasHdl,
  248.                         (*appAliasHdl)->aliasSize,
  249.                         &aliasDesc );
  250.  
  251.     HUnlock( (Handle) appAliasHdl );
  252.     DisposeHandle( (Handle)appAliasHdl );
  253.  
  254.     if ( err ){
  255.         return err;
  256.     }    
  257.  
  258.     /* Now make a list of the alias descriptor.  There is only one element in this
  259.      * list
  260.      */
  261.     
  262.     err = AECreateList( (Ptr)NULL, (Size)0, false, &aliasList );
  263.     
  264.     if ( err ){
  265.         return err;
  266.     }
  267.     
  268.     err = AEPutDesc( &aliasList, 1L, &aliasDesc );
  269.     
  270.     if ( err ){
  271.         return err;
  272.     }
  273.  
  274.     err = AEDisposeDesc( &aliasDesc );
  275.     if ( err ){
  276.         return err;
  277.     }
  278.     
  279.     err = AEPutParamDesc( &launchEvent,
  280.                             keySelection,
  281.                             &aliasList );
  282.     if ( err ){
  283.         return err;
  284.     }
  285.  
  286.     err = AEDisposeDesc( &aliasList );
  287.     if ( err ){
  288.         return err;
  289.     }
  290.  
  291.     err = AESend( &launchEvent,
  292.                     &replyEvent,
  293.                     kAEWaitReply + kAECanInteract,        /* Don't allow later switch */
  294.                     kAENormalPriority,
  295.                     1800,                                // Thirty seconds; browser can take a long time to initialize
  296.                     (AEIdleUPP)NULL,
  297.                     (AEFilterUPP)NULL );
  298.     
  299.     if ( err ){
  300.         return err;
  301.     }
  302.     err = AEDisposeDesc( &launchEvent );
  303.     if ( err ){
  304.         return err;
  305.     }
  306.     
  307.     err = AEDisposeDesc( &replyEvent );
  308.     if ( err ){
  309.         return err;
  310.     }
  311.     
  312.     return noErr;
  313. }
  314.